#include "ArchListaInvertida.h"


ArchListaInvertida::ArchListaInvertida() { }

ArchListaInvertida::~ArchListaInvertida() {
	cerrar();
}


void ArchListaInvertida::abrir(std::string nombre){
	this->_arch.abrirArch(this->_header, nombre);
}

void ArchListaInvertida::crear(std::string nombre){
	this->_arch.crearArch(this->_header, nombre);
}

void ArchListaInvertida::cerrar(){
	if (!this->_arch.is_open()) return;

	this->_arch.guardar(this->_header, 0);
	this->_arch.cerrar();
}


int ArchListaInvertida::guardarLista(const BloqueListaInvertida &bli, int pos){
	if (pos == -1){
		pos = this->_header.getPosBloqueLibre();

		// Hay que agregar un bloque mas al archivo
		if (pos == -1) this->_header.setCantBloques( this->_header.getCantBloques()+1 );

	} else {
		// No se permite guardar donde esta la cabecera
		++pos;
		if (pos < 1 || pos >= this->_header.getCantBloques()){
			throw std::runtime_error("Se trata de guardar un bloque fuera del rango permitido");
		}
	}

	int posGuardado = this->_arch.guardar(const_cast<BloqueListaInvertida&>(bli), pos);

	this->_header.actualizarEspacioBloque(posGuardado, bli.getTamBloque() - bli.getSize());
	this->_arch.guardar(this->_header, 0);

	// Porque no se permite el acceso al bloque cero hay que correr todos los valores
	--posGuardado;
	return posGuardado;
}


void ArchListaInvertida::leerLista(BloqueListaInvertida &bli, int pos){
	// No se puede permitir leer la cabecera
	++pos;
	if (pos <1 || pos >= this->_header.getCantBloques()){
		throw std::runtime_error("La posicion de lectura esta fuera del rango permitido");
	}

	this->_arch.leer(bli, pos);
}


void ArchListaInvertida::borrarLista(int pos){
	// No se permite borrar la cabecera
	++pos;
	if (pos <1 || pos >= this->_header.getCantBloques()){
		throw std::runtime_error("La posicion de borrado esta fuera del rango del archivo");
	}

	bool exito = this->_arch.borrarBloque(pos);
	if (exito) this->_header.liberarBloque(pos);
}


bool ArchListaInvertida::is_open() const{
	return this->_arch.is_open();
}

unsigned int ArchListaInvertida::getCantBloques() const{
	return this->_header.getCantBloques();
}


